﻿#include "MyOpenGL.h"
#include <QOpenGLShaderProgram>
#include <QOpenGLTexture>

#define SHADER(x) #x

MyOpenGL::MyOpenGL(QWidget *parent)
    : QOpenGLWidget(parent)
{

}

MyOpenGL::~MyOpenGL()
{

}

void MyOpenGL::initializeGL()
{
    for(int i = 0; i < 2; ++i)
    {
        textures[i] = new QOpenGLTexture(QImage(QString(":/side%1.png").arg(i + 1)).mirrored());
    }
    initializeOpenGLFunctions();

    QOpenGLShader *vshader = new QOpenGLShader(QOpenGLShader::Vertex, this);
    const char *vsrc = SHADER(
        #version 330\n
        in vec4 vPosition;
        in vec2 vTexCoord;
        out vec2 texCoord;
        uniform mat4 matrix;
        void main() {
            texCoord = vTexCoord;
            gl_Position = matrix * vPosition;
        }
    );
    vshader->compileSourceCode(vsrc);

    QOpenGLShader *fshader = new QOpenGLShader(QOpenGLShader::Fragment, this);
    const char *fsrc = SHADER(
        #version 330\n
        uniform sampler2D tex;
        in vec2 texCoord;
        out vec4 fColor;
        void main() {
            fColor = texture(tex, texCoord);
        }
    );
    fshader->compileSourceCode(fsrc);

    // 创建着色器
    program = new QOpenGLShaderProgram;
    program->addShader(vshader);
    program->addShader(fshader);

    program->link();
    program->bind();

}

void MyOpenGL::paintGL()
{
    int w = width();
    int h = height();
    int side = qMin(w, h);
    glViewport((w - side)/2, (h - side)/2, side, side);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // 顶点位置
    GLfloat vertices[2][4][3] = {
        {{-0.8f, 0.8f, 0.8f}, {-0.8f, -0.8f, 0.8f}, {0.8f, -0.8f, 0.8f}, {0.8f, 0.8f, 0.8f}},
        {{0.8f, 0.8f, 0.8f}, {0.8f, -0.8f, 0.8f}, {0.8f, -0.8f, -0.8f}, {0.8f, 0.8f, -0.8f}}
    };

    vbo.create();
    vbo.bind();
    vbo.allocate(vertices, 40*sizeof(GLfloat));

    GLuint vPosition = program->attributeLocation("vPosition");
    program->setAttributeBuffer(vPosition, GL_FLOAT, 0, 3, 0);
    glEnableVertexAttribArray(vPosition);

    // 纹理坐标
    GLfloat coords[2][4][2] = {
        { {0.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f} },
        { {0.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f} }
    };
    vbo.write(24*sizeof(GLfloat), coords, 16*sizeof(GLfloat));
    GLuint vTexCoord = program->attributeLocation("vTexCoord");
    program->setAttributeBuffer(vTexCoord, GL_FLOAT, 24*sizeof(GLfloat), 2, 0);
    glEnableVertexAttribArray(vTexCoord);
    program->setUniformValue("tex", 0);

    QMatrix4x4 matrix;
    matrix.perspective(45.0f, (GLfloat)w/(GLfloat)h, 0.1f, 100.0f);
    matrix.translate(0, 0, -3);
    matrix.rotate(-60, 0, 1, 0);    // 绕Y轴逆时针旋转
    program->setUniformValue("matrix", matrix);

    // 绘制 2面
    for(int i = 0; i < 2; i++)
    {
        textures[i]->bind();
        glDrawArrays(GL_TRIANGLE_FAN, i*4, 4);
    }

}

void MyOpenGL::resizeGL(int w, int h)
{

}
